package top.atcra.rpc.protection.circuitBreaker.counter;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicLong;

@Slf4j
public class FixWindowErrorRateCounter implements ErrorRateCounter {

    private volatile long timeBase;
    private final AtomicLong totalRequests = new AtomicLong(0);
    private final AtomicLong totalErrors = new AtomicLong(0);
    private final ScheduledExecutorService
            executor = Executors.newSingleThreadScheduledExecutor(r -> {
                Thread thread = new Thread(r);
                thread.setDaemon(true);
                return thread;
            });
    public FixWindowErrorRateCounter(int windowDuration_ms) {
        timeBase = System.currentTimeMillis();
        executor.scheduleAtFixedRate(() -> {
            totalRequests.set(0);
            totalErrors.set(0);
            timeBase = System.currentTimeMillis();
            log.debug("Reset error rate counter.");
        }, windowDuration_ms, windowDuration_ms, java.util.concurrent.TimeUnit.MILLISECONDS);
    }
    @Override
    public void recordRequest(boolean success) {
        totalRequests.incrementAndGet();
        if (!success) {
            totalErrors.incrementAndGet();
        }
    }

    @Override
    public double getErrorRate() {
        double totalRequests_ = totalRequests.get(), totalErrors_ = totalErrors.get();
        return totalRequests_==0?0.0:totalErrors_/totalRequests_;
    }
}
